package org.jeecg.modules.zcgl.tencent.service.impl;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.zcgl.entity.*;
import org.jeecg.modules.zcgl.enums.PayStatusEnum;
import org.jeecg.modules.zcgl.enums.WxMpErrorMsgEnum;
import org.jeecg.modules.zcgl.mapper.*;
import org.jeecg.modules.zcgl.tencent.entity.RemindLog;
import org.jeecg.modules.zcgl.tencent.mapper.CustomerAttentionMapper;
import org.jeecg.modules.zcgl.tencent.mapper.RemindLogMapper;
import org.jeecg.modules.zcgl.tencent.service.IWxSendMessageService;
import org.jeecg.modules.zcgl.tencent.service.IWxTokenService;
import org.jeecg.modules.zcgl.tencent.service.http.HttpService;
import org.jeecg.modules.zcgl.tencent.vo.SendMessageResponse;
import org.jeecg.modules.zcgl.tencent.vo.WxTMessage;
import org.jeecg.modules.zcgl.util.WxWebUrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class WxSendMessageServiceImpl extends AbstractWxService implements IWxSendMessageService {

    //    @Autowired
//    private IWxPayConfig iWxPayConfig;
    @Autowired
    private IWxTokenService wxTokenService;
    @Autowired
    private HttpService httpService;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailsMapper orderDetailsMapper;
    @Autowired
    private ReceivablesInfoMapper receivablesInfoMapper;
    @Autowired
    private LeaseContractInfoMapper leaseContractInfoMapper;
    @Autowired
    private CustomerInfoMapper customerInfoMapper;
    @Autowired
    private AssetInfoMapper assetInfoMapper;
    @Autowired
    private AssetInfoSubMapper assetInfoSubMapper;
    @Autowired
    private CustomerAttentionMapper customerAttentionMapper;
    @Autowired
    private RemindLogMapper remindLogMapper;

    @Autowired
    private ISysDictService sysDictService;

    @Value("${weChat.payment_reminder_template_id}")
    private String paymentReminderTemplateId;
    @Value("${weChat.payment_reminder_url}")
    private String paymentReminderUrl;

    @Value("${weChat.payment_successful_template_id}")
    private String paymentSuccessfulTemplateId;
    @Value("${weChat.payment_successful_url}")
    private String paymentSuccessfulUrl;

    DecimalFormat df4 = new DecimalFormat("#,##0.00");

    @Override
    public boolean paymentReminder(String receivablesId) {

        boolean reBool = false;
        ReceivablesInfo receivablesInfo = receivablesInfoMapper.selectById(receivablesId);
        WxTMessage message = new WxTMessage();
        message.setTemplate_id(paymentReminderTemplateId);
        message.setUrl(paymentReminderUrl);
        if (receivablesInfo != null && receivablesInfo.getPayStatus().compareTo(PayStatusEnum.UNPAID.getStatus()) == 0
                && receivablesInfo.getAmountConfirmation().intValue() == 1) {
            StringBuffer sb = new StringBuffer();
            if (StringUtils.isNotBlank(receivablesInfo.getAssetId())) {
                List<AssetInfo> assetInfoList = assetInfoMapper.selectBatchIds(Arrays.asList(receivablesInfo.getAssetId().split(CommonConstant.DEFAULT_SEPARATOR)));
                if (assetInfoList != null) {
                    assetInfoList.forEach(assetInfo -> {
                        sb.append(assetInfo.getSite() + ",");
                    });
                    sb.deleteCharAt(sb.length() - 1);

                    if (StringUtils.isNotBlank(receivablesInfo.getAssetSubIds()) && assetInfoList.size() == 1) {
                        String[] ids = receivablesInfo.getAssetSubIds().split(CommonConstant.DEFAULT_SEPARATOR);
                        List<AssetInfoSub> assetInfoSubList = (List<AssetInfoSub>) assetInfoSubMapper.selectBatchIds(Arrays.asList(ids));
                        if (assetInfoSubList != null) {
                            sb.append("【");
                            assetInfoSubList.forEach(assetInfoSub -> {
                                sb.append(assetInfoSub.getRoomName() + ",");
                            });
                            sb.deleteCharAt(sb.length() - 1);
                            sb.append("】");
                        }
                    }
                }
            }
//            AssetInfo assetInfo = assetInfoMapper.selectById(receivablesInfo.getAssetId());
//            sb.append(assetInfo != null ? assetInfo.getAssetName() : "");
//            if (StringUtils.isNotBlank(receivablesInfo.getAssetSubIds())) {
//                sb.append("【");
//                String[] assetSubIds = receivablesInfo.getAssetSubIds().split(CommonConstant.DEFAULT_SEPARATOR);
//                for (int i = 0; i < assetSubIds.length; i++) {
//                    AssetInfoSub assetInfoSub = assetInfoSubMapper.selectById(assetSubIds[i]);
//                    if (i > 0) {
//                        sb.append(",");
//                    }
//                    sb.append(assetInfoSub != null ? assetInfoSub.getRoomName() : "");
//                }
//                sb.append("】");
//            }
//
//            String first = "尊敬的租户您好！您有"
//                    + sysDictService.queryDictTextByKey("payment_instructions", String.valueOf(receivablesInfo.getPaymentInstructions()))
//                    + "待缴纳，请及时缴纳。";
//            StringBuffer keyword1 = new StringBuffer(DateUtils.formatDate(receivablesInfo.getStartTime()) + "至"
//                    + DateUtils.formatDate(receivablesInfo.getEndTime()));
//            if (sb.length() > 0) {
//                keyword1.append("\r\n资产名称：" + sb.toString());
//            }
//            keyword1.append("\r\n应缴金额：￥" + df4.format(receivablesInfo.getAmountMoney()));
//            String keyword2 = DateUtils.formatDateTime();
//            CustomerInfo customerInfo = customerInfoMapper.selectById(receivablesInfo.getCustomerId());
//            String keyword3 = customerInfo.getName();
//
////                {{first.DATA}} 应缴周期：{{keyword1.DATA}} 提醒时间：{{keyword2.DATA}} 应缴用户：{{keyword3.DATA}} {{remark.DATA}}
//            message.addParams("first", first, "");
//            message.addParams("keyword1", keyword1.toString(), "");
//            message.addParams("keyword2", keyword2, "");
//            message.addParams("keyword3", keyword3, "");
//            message.addParams("remark", "点击查看详情并完成缴费。", "");

            StringBuffer first = new StringBuffer("尊敬的租户您好！您有"
                    + sysDictService.queryDictTextByKey("payment_instructions", String.valueOf(receivablesInfo.getPaymentInstructions()))
                    + "待缴纳，请及时缴纳。");
            if (sb.length() > 0) {
                first.append("\r\n\n资产名称：\t" + sb.toString());
            }
            first.append("\r\n应缴金额：\t￥" + df4.format(receivablesInfo.getAmountMoney()));

            String keyword1 = DateUtils.formatDate(receivablesInfo.getStartTime()) + "至"
                    + DateUtils.formatDate(receivablesInfo.getEndTime());
            String keyword2 = DateUtils.formatDateTime();

            message.addParams("first", first.toString(), "");
            message.addParams("keyword1", keyword1, "");
            message.addParams("keyword2", keyword2, "");
            message.addParams("remark", "点击查看详情并完成缴费。", "");

            if (StringUtils.isNotBlank(receivablesInfo.getCustomerId())) {
                List<CustomerInfo> customerInfos = customerInfoMapper.selectBatchIds(Arrays.asList(receivablesInfo.getCustomerId().split(CommonConstant.DEFAULT_SEPARATOR)));
                if (customerInfos != null) {
                    for (CustomerInfo customerInfo : customerInfos) {
                        String keyword3 = customerInfo.getName();
                        message.addParams("keyword3", keyword3, "");

                        List<String> openIds = customerAttentionMapper.selectOpenIdsByCustomerId(receivablesInfo.getCustomerId());
                        if (openIds == null || openIds.size() == 0) {
                            log.error("没有绑定微信账号，提醒失败--->{}", JSON.toJSONString(message));
                            throw new JeecgBootException("没有绑定微信账号，提醒失败！");
                        }
                        for (String openId : openIds) {
                            message.setTouser(openId);//接受者的openID
                            SendMessageResponse messageResponse = this.sendMessage(message, true);
                            if (messageResponse.getErrcode() == 0) {
                                reBool = true;
                            }

                            RemindLog remindLog = new RemindLog();
                            if (messageResponse == null) {
                                remindLog.setStatus(0);
                            } else {
                                remindLog.setStatus(messageResponse.getErrcode() == 0 ? 1 : 0);
                                remindLog.setContent(JSON.toJSONString(message));
                                remindLog.setRemark(JSON.toJSONString(messageResponse));
                            }
                            remindLog.setType(1);
                            remindLog.setOpenId(openId);
                            remindLog.setCustomerId(receivablesInfo.getCustomerId());
                            remindLog.setReceivablesId(receivablesInfo.getId());
                            remindLogMapper.insert(remindLog);
                        }
                    }
                }
            }
        }
        if (reBool) {
            receivablesInfo.setIsRemind(1);
            receivablesInfo.setRemindNum(receivablesInfo.getRemindNum() == null ? 1 : receivablesInfo.getRemindNum() + 1);
            receivablesInfoMapper.updateById(receivablesInfo);
        }
        return reBool;
    }

    @Override
    public Map<String, Boolean> paymentReminder(String[] receivablesIds) {
        if (receivablesIds == null || receivablesIds.length == 0) {
            return null;
        }

        Map<String, Boolean> re = new HashMap<>();
        Arrays.stream(receivablesIds).forEach(receivablesId -> {
            try {
                re.put(receivablesId, this.paymentReminder(receivablesId));
            } catch (JeecgBootException e) {
                re.put(e.getMessage(), false);
//                e.printStackTrace();
            } catch (Exception e) {
                re.put(e.getMessage(), false);
//                e.printStackTrace();
            }
        });
        return re;
    }

    @Override
    public SendMessageResponse paymentSuccessful(String openId, String orderId) {

        //根据订单查询出订单ID
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            return null;
        }

        WxTMessage message = new WxTMessage();
        message.setTemplate_id(paymentSuccessfulTemplateId);
        message.setTouser(openId);//接受者的openID
        message.setUrl(paymentSuccessfulUrl);

//        List<OrderDetails> orderDetailsList = orderDetailsMapper.selectByMainId(orderId);
//        for (OrderDetails orderDetails : orderDetailsList) {
//
//        }
//        ReceivablesInfo receivablesInfo = receivablesInfoMapper.selectById(order.get)
//        String first = "您好，您的合同【"+order.geT+"】"


//        	{{first.DATA}} 项目编号：{{keyword1.DATA}} 缴费金额：{{keyword2.DATA}} 缴费时间：{{keyword3.DATA}} {{remark.DATA}}
        message.addParams("first", "尊敬的租户您好！您已缴费成功。", "");
        message.addParams("keyword1", order.getOrderNo(), "");
        message.addParams("keyword2", "￥" + df4.format(order.getAmountMoney() == null ? 0 : order.getAmountMoney()), "");
//        message.addParams("keyword3", DateUtils.datetimeFormat.get().format(order.getPayDate() == null ? new Date() : order.getPayDate()), "");
        message.addParams("remark", "感谢您的支持，点击查看详情！", "");

        SendMessageResponse sendMessageResponse = this.sendMessage(message, true);
        RemindLog remindLog = new RemindLog();
        if (sendMessageResponse == null) {
            remindLog.setStatus(0);
        } else {
            remindLog.setStatus(sendMessageResponse.getErrcode() == 0 ? 1 : 0);
            remindLog.setContent(JSON.toJSONString(message));
            remindLog.setRemark(String.valueOf(sendMessageResponse.getMsgid()));
        }
        remindLog.setType(2);
//        remindLog.setOpenId(order.getOpenId());
        remindLog.setCustomerId(order.getCustomerId());
        remindLog.setContent(JSON.toJSONString(message));
        remindLogMapper.insert(remindLog);
        return sendMessageResponse;
    }

    private SendMessageResponse sendMessage(WxTMessage message, boolean first) {
        String accessToken = wxTokenService.getWxToken();

        // params
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put(WxWebUrl.UrlParam.ACCESS_TOKEN, accessToken);
        SendMessageResponse response = null;
        try {
            response = httpService.post(this.fmtReqWebsUrl(WxWebUrl.POST_SEND_MESSAGE, paramMap), JSON.toJSONString(message), SendMessageResponse.class);

            if (response != null && first
                    && (response.getErrcode() == WxMpErrorMsgEnum.CODE_42001.getCode()
                    || response.getErrcode() == WxMpErrorMsgEnum.CODE_40001.getCode()
                    || response.getErrcode() == WxMpErrorMsgEnum.CODE_40014.getCode())) {
                wxTokenService.refreshtWxToken();
                return sendMessage(message, false);
            }
        } catch (Exception e) {
            log.error("sendMessage() exception. ", e);
        }
        return response;
    }

}
